/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lestr.udm.core2.managers.storage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lestr.udm.core2.DefaultDataManager;
import org.lestr.udm.core2.GdmException;
import org.lestr.udm.core2.IDataManager.IParameters;
import org.lestr.udm.core2.IDataManager.ISession;
import org.lestr.udm.core2.StreamUtil;

/**
 *
 * @author pibonnin
 */
public class SemiPersistentDataManager extends DefaultDataManager<SemiPersistentDataManager.DefaultSession, SemiPersistentDataManager.Parameters> {

    private Parameters parameters;

    public SemiPersistentDataManager() {

        parameters = new Parameters();

    }// END Constructor

    @Override
    public Parameters getParameters() {
        return super.getParameters();
    }

    @Override
    public ISession openSession() throws GdmException {
        return new Session();
    }

    private class Session extends DefaultDataManager.DefaultSession {

        @Override
        public boolean addData(String id) throws GdmException {

            try {
                return new File(parameters.getDirectoryAddress() + File.pathSeparator + id).createNewFile();
            } catch (IOException ex) {
                Logger.getLogger(SemiPersistentDataManager.class.getName()).log(Level.SEVERE, null, ex);
                throw new GdmException(ex);
            }

        }

        @Override
        public boolean existsData(String id) throws GdmException {

            return new File(parameters.getDirectoryAddress() + File.pathSeparator + id).exists();

        }

        @Override
        public boolean removeData(String id) throws GdmException {

            return new File(parameters.getDirectoryAddress() + File.pathSeparator + id).delete();

        }

        @Override
        public boolean setDataValue(String id, InputStream datas) throws GdmException {

            try {
                StreamUtil.copy(datas, new FileOutputStream(parameters.getDirectoryAddress() + File.pathSeparator + id));
            } catch (FileNotFoundException ex) {
                Logger.getLogger(SemiPersistentDataManager.class.getName()).log(Level.SEVERE, null, ex);
                throw new GdmException(ex);
            } catch (IOException ex) {
                Logger.getLogger(SemiPersistentDataManager.class.getName()).log(Level.SEVERE, null, ex);
                throw new GdmException(ex);
            }

            return true;

        }

        @Override
        public InputStream getDataValue(String id) throws GdmException {

            try {
                return new FileInputStream(parameters.getDirectoryAddress() + File.pathSeparator + id);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(SemiPersistentDataManager.class.getName()).log(Level.SEVERE, null, ex);
                throw new GdmException(ex);
            }

        }

        @Override
        public long getDataLength(String id) throws GdmException {

            return new File(parameters.getDirectoryAddress() + File.pathSeparator + id).length();

        }
    }

    public class Parameters extends DefaultDataManager.DefaultParameters {

        private String directoryAddress;

        public Parameters() {

            directoryAddress = System.getProperty("java.io.tmpdir") + File.pathSeparator + UUID.randomUUID().toString();

            File directory = new File(directoryAddress);
            directory.mkdir();

        }

        /**
         * @return the directoryAddress
         */
        public String getDirectoryAddress() {
            return directoryAddress;
        }

        /**
         * @param directoryAddress the directoryAddress to set
         */
        public void setDirectoryAddress(String directoryAddress) {
            this.directoryAddress = directoryAddress;
        }
    }
}
